package com.axend.lib_base.ext

import android.app.Activity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.axend.lib_base.R
import java.lang.reflect.ParameterizedType

/**
 * Fragment相关扩展
 */

/**
 * fragment批处理，自动commit
 */
fun FragmentActivity.fragmentManager(action: FragmentTransaction.() -> Unit) {
    supportFragmentManager.beginTransaction()
        .apply { action() }
        .commitAllowingStateLoss()
}

//自动替换fragment
fun FragmentActivity.replaceFragment(
    layoutId: Int,
    f: Fragment,
    bundle: Array<out Pair<String, Any?>>? = null
) {
    if (bundle != null) f.arguments = bundle.toBundle()
    supportFragmentManager.beginTransaction()
        .replace(layoutId, f)
        .commitAllowingStateLoss()
}

//添加fragment
fun FragmentActivity.addFragment(
    layoutId: Int,
    f: Fragment,
    hideFragment: Fragment?,
    bundle: Array<out Pair<String, Any?>>? = null,
    addToBackStack: Boolean
) {
    if (bundle != null) f.arguments = bundle.toBundle()
    supportFragmentManager.beginTransaction().let {
        if (hideFragment != null) {
            it.hide(hideFragment)
        }
        it.add(layoutId, f, f.javaClass.simpleName)
        it.setCustomAnimations(
            R.anim.common_in_from_left,
            R.anim.common_out_to_right,
            R.anim.common_in_from_left,
            R.anim.common_out_to_right
        )
        if (addToBackStack) {
            it.addToBackStack(f.javaClass.simpleName)
        }
        it.commitAllowingStateLoss()

    }
}

/*预加载fragment*/
fun Fragment.preloadFragment(
    activity: FragmentActivity?,
    layoutId: Int,
    f: Fragment,
    bundle: Array<out Pair<String, Any?>>? = null
) {
    if (bundle != null) f.arguments = bundle.toBundle()
    activity?.supportFragmentManager?.beginTransaction()
        ?.add(layoutId, f, f.javaClass.simpleName)
        ?.setMaxLifecycle(f, Lifecycle.State.RESUMED)
        ?.hide(f)
        ?.commitAllowingStateLoss()
}

/*显示预加载的fragment并移除掉上一个fragment*/
fun Fragment.showPreloadFragment(
    activity: FragmentActivity?,
    layoutId: Int,
    f: Fragment,
    hideFragment: Fragment,
    bundle: Array<out Pair<String, Any?>>? = null
) {
    if (bundle != null) f.arguments = bundle.toBundle()
    activity?.supportFragmentManager?.apply {
        val existingFragment = findFragmentByTag(f.javaClass.simpleName)
        beginTransaction().let { transaction ->
            if (existingFragment == null) {
                transaction.add(layoutId, f, f.javaClass.simpleName)
            }
            transaction.apply {
                hide(hideFragment)
                show(f)
                addToBackStack(f.javaClass.simpleName)
                commitAllowingStateLoss() // 使用 commit 而不是 commitAllowingStateLoss
            }
        }
    }

}


/*fragment拓展函数*/
fun Fragment.addFragment(
    activity: FragmentActivity?,
    layoutId: Int,
    f: Fragment,
    hideFragment: Fragment?,
    bundle: Array<out Pair<String, Any?>>? = null,
    addToBackStack: Boolean = false
) {
    if (bundle != null) f.arguments = bundle.toBundle()
    activity?.supportFragmentManager?.beginTransaction().let {
        if (hideFragment != null) {
            it?.hide(hideFragment)
        }
        it?.add(layoutId, f, f.javaClass.simpleName)
        it?.setCustomAnimations(
            R.anim.common_in_from_left,
            R.anim.common_out_to_right,
            R.anim.common_in_from_left,
            R.anim.common_out_to_right
        )
        if (addToBackStack) {
            it?.addToBackStack(f.javaClass.simpleName)
        }
        it?.commitAllowingStateLoss()
    }
}

/*fragment拓展函数
* 会移除上一个fragment事务*/
fun Fragment.replaceFragment(
    activity: FragmentActivity?,
    layoutId: Int,
    f: Fragment,
    removeFragment: Fragment?,
    bundle: Array<out Pair<String, Any?>>? = null,
    addToBackStack: Boolean = false
) {
    if (bundle != null) f.arguments = bundle.toBundle()
    activity?.supportFragmentManager?.beginTransaction().let {
        it?.replace(layoutId, f, f.javaClass.simpleName)
        it?.setCustomAnimations(
            R.anim.common_in_from_left,
            R.anim.common_out_to_right,
            R.anim.common_in_from_left,
            R.anim.common_out_to_right
        )
        activity?.supportFragmentManager?.popBackStack(
            removeFragment?.javaClass?.simpleName,
            FragmentManager.POP_BACK_STACK_INCLUSIVE
        )
        if (addToBackStack) {
            it?.addToBackStack(f.javaClass.simpleName)
        }
        it?.commit()
    }
}

fun Fragment.clearAllFragments(activity: FragmentActivity?) {
    activity?.supportFragmentManager?.fragments?.forEach { fragment ->
        activity.supportFragmentManager.beginTransaction()
            .remove(fragment)
            .commitNowAllowingStateLoss()
    }
}

//判断上一个fragment类型
fun Fragment.isPreFragment(clazz: Class<*>): Boolean {
    return activity?.supportFragmentManager?.fragments?.get(0)?.javaClass == clazz
}

//隐藏
fun FragmentActivity.hideFragment(f: Fragment) {
    supportFragmentManager.beginTransaction()
        .hide(f)
        .commitAllowingStateLoss()
}

//展示
fun FragmentActivity.showFragment(f: Fragment) {
    supportFragmentManager.beginTransaction()
        .show(f)
        .commitAllowingStateLoss()
}

//移除
fun FragmentActivity.removeFragment(f: Fragment) {
    supportFragmentManager.beginTransaction()
        .remove(f)
        .commitAllowingStateLoss()
}

//移除
fun Fragment.removeFragment(f: Fragment) {
    activity?.removeFragment(f)
    activity?.supportFragmentManager?.fragments?.remove(f)
}

//替换
fun Fragment.replaceFragment(
    layoutId: Int,
    f: Fragment,
    bundle: Array<out Pair<String, Any?>>? = null
) {
    if (bundle != null) f.arguments = bundle.toBundle()
    childFragmentManager.beginTransaction()
        .replace(layoutId, f)
        .commitAllowingStateLoss()
}

fun Fragment.addFragment(
    layoutId: Int,
    f: Fragment,
    bundle: Array<out Pair<String, Any?>>? = null
) {
    if (bundle != null) f.arguments = bundle.toBundle()
    childFragmentManager.beginTransaction()
        .add(layoutId, f)
        .commitAllowingStateLoss()
}

fun Fragment.hideFragment(f: Fragment) {
    childFragmentManager.beginTransaction()
        .hide(f)
        .commitAllowingStateLoss()
}

fun Fragment.showFragment(f: Fragment) {
    childFragmentManager.beginTransaction()
        .show(f)
        .commitAllowingStateLoss()
}

//fun Fragment.removeFragment(f: Fragment) {
//    childFragmentManager.beginTransaction()
//        .remove(f)
//        .commitAllowingStateLoss()
//}

//传入Fragment对应的ViewModel-class实例，获取ViewModel对象
fun <T : ViewModel> Fragment.getVM(clazz: Class<T>) = ViewModelProvider(this).get(clazz)

//传入Fragment的容器Activity对象中ViewModel-class实例，获取Activity的ViewModel对象
fun <T : ViewModel> Fragment.getActivityVM(clazz: Class<T>) =
    ViewModelProvider(requireActivity()).get(clazz)

//获取泛型的实例
fun <VM> getVMCls(cls: Any): VM {
    return (cls.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as VM
}